package com.tree.thread.pubsub;

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Function;

/**
 * @ClassName com.tree.thread.pubsub
 * Description: <类功能描述>. <br>
 * <p>
 * 使用阻塞队列实现生产者消费者
 * </p>
 * @Author tree
 * @Date 2019-11-02 12:59
 * @Version 1.0
 */
public class BlockingQueueTest {

    public static void main(String[] args) {
        BlockingQueueStorage storage = new BlockingQueueStorage();
        for(int i = 0; i< 3; i++){
            new Thread(new Producer(storage),"生产者-"+i).start();
            new Thread(new Consumer(storage),"消费者-"+i).start();
        }
    }

    static class BlockingQueueStorage implements IStorage{
        private  int count = 0;

        private BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(10);

        @Override
        public void produce(){

            try {
                String threadName = Thread.currentThread().getName();

                blockingQueue.put(count);
                //注意 count++必须在阻塞之后， 否则多线程在阻塞之前会改变count的值。
                count++;
                System.out.println("生产者【" + threadName+ "】生产一个产品，现库存" + count+", size = "+blockingQueue.size());

            } catch (InterruptedException e) {
                e.printStackTrace();
            }


        }

        @Override
        public void consume(){
            try {
                String threadName = Thread.currentThread().getName();

                int tmp = blockingQueue.take();
                count--;
                System.out.println("消费者【" + threadName+ "】消费一个产品，现库存" + count+", 取出的数为"+tmp+"，size = "+blockingQueue.size());

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
